<!--
 * @Descripttion: 
 * @Author: voanit
 * @Date: 2022-03-04 18:13:35
 * @LastEditors: voanit
 * @LastEditTime: 2022-03-06 10:08:22
-->
<template>
  <div class="goods-sku">
    <!-- <pre>==={{ goods }}</pre> -->
    <dl v-for="specs in goods.specs" :key="specs.name">
      <dt>{{ specs.name }}</dt>
      <dd>
        <!-- <img
          class="selected"
          src="https://yanxuan-item.nosdn.127.net/d77c1f9347d06565a05e606bd4f949e0.png"
          alt=""
        />
        <img
          class="disabled"
          src="https://yanxuan-item.nosdn.127.net/d77c1f9347d06565a05e606bd4f949e0.png"
          alt=""
        /> -->

        <span v-for="(spec, index) in specs.values" :key="index">
          <!-- ==
          <pre>{{ spec }}</pre> -->

          <img
            :class="{ selected: spec.selected, disabled: spec.disabled }"
            @click="changeSku(spec, specs.values)"
            v-if="spec.picture"
            :src="spec.picture"
            alt=""
          />
          <span
            v-else
            :class="{ selected: spec.selected, disabled: spec.disabled }"
            @click="changeSku(spec, specs.values)"
            >{{ spec.name }}</span
          >
        </span>
      </dd>
    </dl>
    <!-- <dl>
      <dt>尺寸</dt>
      <dd>
        <span class="disabled">10英寸</span>
        <span class="selected">20英寸</span>
        <span>30英寸</span>
      </dd>
    </dl>
    <dl>
      <dt>版本</dt>
      <dd>
        <span>美版</span>
        <span>港版</span>
      </dd>
    </dl> -->
  </div>
</template>
<script>
/* 
sku步骤总结
1-点击sku高亮切换显示 ===排他
2-获取字典集合 封装 getPathMap()
3-定义初次进入禁用sku  封装 updateDisabledStatus
4-点击重新展示禁用
  4-1 定义选中的规格的值 getSelectedSpec  =====[黑色，中国，30cm]
  4-2 根据定义选中的规格值重新从字典集合中获取禁用状态 在 updateDisabledStatus里面写   ====【最难理解】
  4-3 点击调用 updateDisabledStatus()
  4-4 获取选中的sku然后从字典集合中查找sku对象，最后返回给父组件
*/

import bwPowerSet from "@/vendor/power-set";

/* 字典集合==所有可能 */
const getPathMap = (skus) => {
  var pathMap = {}; //字典路径集合  {黑色，日本，’黑色日本‘,30cm,}
  skus.forEach((sku) => {
    //1- 表示收集的是有效的sku
    if (sku.inventory) {
      // 表示收集的是有效的sku
      // 2-获取sku属性数组
      var specs = sku.specs.map((spec) => spec.valueName); //[黑色，日本，30cm]===
      //console.log(specs, 556677);
      // 3-通过算法获取所有可能子集 [[]]
      const powerSet = bwPowerSet(specs);
      /*   powerSet有8组
      [
        0: []
        1: ['黑色']
        2: ['日本']
        3: (2) ['黑色', '日本']
        4: ['30cm']
        5: (2) ['黑色', '30cm']
        6: (2) ['日本', '30cm']
        7: (3) ['黑色', '日本', '30cm']
      ]
      */
      //console.log(powerSet, 8899);
      // 4-获取字典对象
      powerSet.forEach((set) => {
        const key = set.join("☆"); // ’‘ 黑色  黑色☆日本   30cm    黑色☆30cm
        if (pathMap[key]) {
          // 表示之前收集过
          pathMap[key].push(sku.id);
        } else {
          //  第一次找到
          pathMap[key] = [sku.id];
        }

        //  pathMap={20cm:[]}
        /*
       pathMap['20cm']=[123]===>pathMap:{20cm:[123，333]}

       */
      });
    }
  });

  return pathMap;
};

/* 定义选中的规格的值 */
const getSelectedSpec = (specs) => {
  const arr = []; // [undefined, undefined, undefined]
  specs.forEach((spec, i) => {
    // 获取所选中的
    var selectedObj = spec.values.find((item) => item.selected);
    if (selectedObj) {
      //  表示有选中的
      arr[i] = selectedObj.name;
    } else {
      // 表示没有被选中的
      arr[i] = undefined;
    }
  });

  return arr; // ['蓝色',undefined,undefined]
};

const updateDisabledStatus = (specs, pathMap) => {
  //  查每一项是否被禁用
  /*
    1-需要每一项的数据进行判断
    2-需要在字典集合中去查找
    */
  //  初次进入获取选中的sku
  var selectedObj = JSON.stringify(getSelectedSpec(specs)); //'[null,null,null]','['蓝色',undefined,undefined]'
  // console.log(selectedObj, 666);
  specs.forEach((spec, i) => {
    var selectVal = JSON.parse(selectedObj); // [null,null,null]     ['蓝色','日本'',undefined]
    spec.values.forEach((item) => {
      // if (pathMap[item.name]) {
      //   //  表示在字典集合中找到了  ====不需要禁用
      //   item.disabled = false;
      // } else {
      //   //  表示没有找到需要禁用
      //   item.disabled = true;
      // }

      selectVal[i] = item.name;
      // console.log(selectVal, 866);
      var key = selectVal.filter((v) => v).join("☆");
      // var key = selectVal.join("☆");
      // console.log(key, 556677);
      if (pathMap[key]) {
        //  表示在字典集合中找到了  ====不需要禁用
        item.disabled = false;
      } else {
        //  表示没有找到需要禁用
        item.disabled = true;
      }
    });
  });
};

const initDefaultSelected = (skuId, goods) => {
  // 根据skuid到skus中查找对应的这一项，然后让其高亮
  const skuObj = goods.skus.find((sku) => sku.id === skuId);
  goods.specs.forEach((spec, i) => {
    spec.values.forEach((item) => {
      item.selected = skuObj.specs[i].valueName === item.name;
    });
  });
};
export default {
  name: "GoodsSku",
  props: {
    goods: {
      type: Object,
      default() {
        return {};
      },
    },
    skuId: {
      type: String,
      default: "1369155865461919746", //skuId:1369155865461919746
    },
  },
  setup(props, { emit }) {
    /* 2-获取字典集合 ====收集所有可能存在一个对象中 */
    const pathMap = getPathMap(props.goods.skus);
    // console.log(pathMap, 88);
    // 1- 点击sku实现选中高亮切换
    const changeSku = (spec, specValue) => {
      // 如果自身是被禁用的 那点击直接终止
      if (spec.disabled) return;
      if (spec.selected) {
        //  selected===动态添加上去的
        // 表示 selected:true
        spec.selected = false;
      } else {
        //  表示 selected:false
        // 排他==关闭其他人
        specValue.forEach((item) => {
          item.selected = false;
        });
        // 照亮自己
        spec.selected = true;
      }

      //3-实现禁用效果展示===点击切换的时候重新判断是否禁用
      updateDisabledStatus(props.goods.specs, pathMap);

      //  获取sku数据值
      const getSelectedSpecArr = getSelectedSpec(props.goods.specs); //  [null,null,null]

      //  获取选中的sku值，并去空
      var newArr = getSelectedSpecArr.filter((v) => v); //  需要去空 [黑色，中国，20cm]
      //  判断是否全部选中了
      console.log(newArr, 444);
      if (newArr.length === props.goods.specs.length) {
        // 从字典中获取skuID
        var skuId = pathMap[newArr.join("☆")][0]; //  pathMap['黑色☆中国☆10cm']==》[124444443]
        // 根据skuId获取sku这一项对象
        var skuObj = props.goods.skus.find((item) => item.id === skuId);
        console.log(skuObj, 7);
        // 将获取的sku数据返回给父组件
        emit("skuChange", {
          skuId: skuObj.id,
          price: skuObj.price,
          oldPrice: skuObj.oldPrice,
          inventory: skuObj.inventory,
          specsText: skuObj.specs
            .reduce((str, item) => `${str} ${item.name}：${item.valueName}`, "")
            .trim(""), // 描述
          // specsText:
        });
      } else {
        // 有没选中的
        emit("change", {});
      }
    };

    //3-实现禁用效果展示
    updateDisabledStatus(props.goods.specs, pathMap);
    // initDefaultSelected(props.skuId, props.goods);
    return { changeSku };
  },
};
</script>
<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      img {
        width: 50px;
        height: 50px;
        .sku-state-mixin ();
      }
      > span span {
        display: inline-block;
        height: 30px;
        line-height: 28px;
        padding: 0 20px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>
